home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Programming Languages Suite
/
ProgramD2.iso
/
Borland
/
Borland C++ V5.02
/
OCFSRC.PAK
/
OLEUTIL.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-05-06
|
9KB
|
438 lines
//----------------------------------------------------------------------------
// ObjectComponents
// Copyright (c) 1994, 1997 by Borland International, All Rights Reserved
//
// $Revision: 2.14 $
//
// OLE Utility class implementations
//----------------------------------------------------------------------------
#include <ocf/pch.h>
#if !defined(OCF_DEFS_H)
# include <ocf/defs.h>
#endif
#if !defined(OCF_OLEUTIL_H)
# include <ocf/oleutil.h>
#endif
#if !defined(WINSYS_STRING_H)
# include <winsys/string.h>
#endif
#if !defined(SERVICES_MEMORY_H)
# include <services/memory.h>
#endif
#if !defined (WINSYS_REGISTRY_H)
# include <winsys/registry.h>
#endif
#if !defined (OCF_OCBOCOLE_H)
# include <ocf/ocbocole.h>
#endif
DIAG_DEFINE_GROUP(OcRefCount, true, 1);
//
//
//
void*
TOleAllocator::Alloc(unsigned long size)
{
void* blk = Mem->Alloc(size);
OLECALL(blk ? 0 : HR_OUTOFMEMORY, "IMalloc::Alloc");
return blk;
}
//
//
//
void
TOleAllocator::Free(void* pv)
{
Mem->Free(pv);
}
//----------------------------------------------------------------------------
// TClassId - GUID/IID/CLSID management implementation
//
//
//
//
TClassId::TClassId(const char* idtxt)
:Text(0)
{
PRECONDITION(idtxt);
OLECALL(::CLSIDFromString(OleStr((char far*)idtxt), &Guid), "Invalid GUID string");
}
//
//
//
TClassId::TClassId(const GUID far& guid, int offset)
:Text(0), Guid(guid)
{
Guid.Data1 += (long)offset;
}
//
//
//
TClassId::TClassId(TGenerate)
:Text(0)
{
OLECALL(::CoCreateGuid(&Guid), "CoCreateGuid");
}
//
//
//
TClassId::~TClassId()
{
delete[] const_cast<char*>(Text);
}
//
//
//
TClassId::operator const char*()
{
if (!Text) {
Text = new char[38+1];
wsprintf(const_cast<char*>(Text),
"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
Guid.Data1, Guid.Data2, Guid.Data3,
Guid.Data4[0], Guid.Data4[1], Guid.Data4[2], Guid.Data4[3],
Guid.Data4[4], Guid.Data4[5], Guid.Data4[6], Guid.Data4[7]);
}
return Text;
}
//
//
//
TBaseClassId::TBaseClassId(const GUID far& guid, int maxAlloc)
:TClassId(guid), MaxAlloc(maxAlloc), Offset(0)
{
}
//
//
//
TBaseClassId::TBaseClassId(const char far* idtxt, int maxAlloc)
:TClassId(idtxt), MaxAlloc(maxAlloc), Offset(0)
{
}
//
//
//
TBaseClassId::TBaseClassId(TGenerate e, int maxAlloc)
:TClassId(e), MaxAlloc(maxAlloc), Offset(0)
{
}
//
//
//
TBaseClassId::TBaseClassId(TRegList& regInfo, int maxAlloc)
:TClassId(), MaxAlloc(maxAlloc), Offset(0)
{
const char* str = regInfo["clsid"];
if (!str)
OLECALL(HR_CLASS_CLASSNOTAVAILABLE, "Missing REGDATA clsid");
OLECALL(::CLSIDFromString(OleStr((char far*)str), &Guid), "Invalid GUID string");
}
//
//
//
TClassId
TBaseClassId::operator [](int offset)
{
if(offset > Offset)
OLECALL(HR_CLASS_CLASSNOTAVAILABLE, "Unassigned GUID");
return TClassId(Guid, offset);
}
//
//
//
int
TBaseClassId::AllocId()
{
++Offset;
if(Offset >= MaxAlloc)
OLECALL(HR_CLASS_CLASSNOTAVAILABLE, "GUID allocation exhausted");
return Offset;
}
//
//
//
int
TBaseClassId::GetOffset(const GUID& guid)
{
unsigned long offset = guid.Data1 - Guid.Data1;
if ( offset >= (unsigned long)Offset &&
((long*)&guid)[1] == ((long*)&Guid)[1] &&
((long*)&guid)[2] == ((long*)&Guid)[2] &&
((long*)&guid)[3] == ((long*)&Guid)[3] )
return int(offset);
else
return -1;
}
//----------------------------------------------------------------------------
// GUID compare routines use by implementations of IUnknown::QueryInterface
// the low-order long word is verifed before calling these routines
// success is indicated by virtue of assigment of the returned interface
//
#if defined(BI_NAMESPACE)
namespace OCF {
#endif
//
//
//
void
CmpGuid12(IUnknown* obj, REFIID req, REFIID ref, void far*far* pif)
{
if ( ((long far*)&req)[1] == ((long far*)&ref)[1] &&
((long far*)&req)[2] == ((long far*)&ref)[2] &&
((long far*)&req)[3] == ((long far*)&ref)[3] ) {
*pif = obj;
obj->AddRef();
}
}
//
//
//
void
CmpGuidOle(IUnknown* obj, REFIID req, void far*far* pif)
{
if ( ((long*)&req)[1] == 0x00000000L &&
((long*)&req)[2] == 0x000000C0L &&
((long*)&req)[3] == 0x46000000L ) {
*pif = obj;
obj->AddRef();
}
}
#if defined(BI_NAMESPACE)
} // namespace OCF
#endif
//----------------------------------------------------------------------------
// TUnknown - standard implementation of IUnknown
//
//
// Handy container to help watch COM object lifetime when debugging
//
#if (__DEBUG >= 2)
# include <classlib/bags.h>
typedef TBagAsVector<TUnknown*> TUnknownBag;
TUnknownBag* UnknownBag;
#endif
//
//
//
TUnknown::TUnknown()
:Outer(&I)
{
#if (__DEBUG >= 2)
if (!UnknownBag)
UnknownBag = new TUnknownBag(100);
UnknownBag->Add(this);
#endif
}
//
//
//
IUnknown&
TUnknown::Aggregate(TUnknown& inner)
{
if (I.Inner)
return I.Inner->Aggregate(inner);
((IUnknown&)inner).AddRef();
I.Inner = &inner;
return *Outer;
}
//
//
//
TUnknown::~TUnknown()
{
#if (__DEBUG >= 2)
UnknownBag->Detach(this);
#endif
TRACEX(OcRefCount, 1,
"~TUnknown() @" << (void*)this << ", RefCnt:" << I.RefCnt);
WARNX(OcRefCount, I.RefCnt != 0, 0,
"~TUnknown() @ " << (void*)this << ", RefCnt:" << I.RefCnt);
// deleted by TUnknownI member
}
//
// QueryObject used when TUnknown is in constructor/destructor
//
HRESULT
TUnknown::QueryObject(const GUID far& /*iid*/, void far* far* /*pif*/)
{
return ResultFromScode(E_NOINTERFACE);
}
//
//
//
HRESULT _IFUNC
TUnknown::TUnknownI::QueryInterface(const GUID far& iid, void far* far* pif)
{
*pif = 0;
if (iid.Data1 == 0) { // IID_IUnknown.Data1
CmpGuidOle(this, iid, pif);
if (*pif)
return NOERROR;
}
if (Host().QueryObject(iid, pif) == NOERROR)
return NOERROR;
if (Inner)
return Inner->ThisUnknown().QueryInterface(iid, pif);
else
return ResultFromScode(E_NOINTERFACE);
}
//
//
//
unsigned long _IFUNC
TUnknown::TUnknownI::AddRef()
{
TRACEX(OcRefCount, 1,
"AddRef on " << _TYPENAME(&Host()) << ' ' << (void*)&Host() << " to " << (RefCnt+1));
return ++RefCnt;
}
//
//
//
unsigned long _IFUNC
TUnknown::TUnknownI::Release()
{
TRACEX(OcRefCount, 1,
"Release on " << _TYPENAME(&Host()) << ' ' << (void*)&Host() << " to " << (RefCnt-1));
if (--RefCnt != 0)
return RefCnt;
if (Inner) {
Inner->ThisUnknown().Release();
Inner = 0;
}
delete &Host();
return 0;
}
//
//
//
unsigned long
TUnknown::GetRefCount()
{
if (Outer == &I)
return I.RefCnt;
Outer->AddRef();
return Outer->Release();
}
//
//
//
TUnknown::TUnknownI::~TUnknownI()
{
// In case destructor called before RefCnt goes to 0
//
if (RefCnt)
::CoDisconnectObject(this,0);// OLE will try to remove external references
}
//----------------------------------------------------------------------------
// Pixel <-> HiMetric conversion routines
//
static int logPixX = 0;
static int logPixY = 0;
//
//
static void
GetScreenMetrics(int& logPixX, int& logPixY)
{
HDC hDCScreen = GetDC(0);
logPixX = GetDeviceCaps(hDCScreen, LOGPIXELSX);
logPixY = GetDeviceCaps(hDCScreen, LOGPIXELSY);
ReleaseDC(0, hDCScreen);
}
//
//
//
void
OcHiMetricToPixel(const SIZEL& sizeHM, SIZEL& sizePix)
{
if (!logPixX || !logPixY)
GetScreenMetrics(logPixX, logPixY);
sizePix.cx = MAP_LOGHIM_TO_PIX(sizeHM.cx, logPixX);
sizePix.cy = MAP_LOGHIM_TO_PIX(sizeHM.cy, logPixY);
}
//
//
//
void
OcPixelToHiMetric(const SIZEL& sizePix, SIZEL& sizeHM)
{
if (!logPixX || !logPixY)
GetScreenMetrics(logPixX, logPixY);
sizeHM.cx = MAP_PIX_TO_LOGHIM(sizePix.cx, logPixX);
sizeHM.cy = MAP_PIX_TO_LOGHIM(sizePix.cy, logPixY);
}
//----------------------------------------------------------------------------
// TLocaleString wrapper method replacements using OLE2 NLS functions for Win16
//
#if defined(BI_PLAT_WIN16)
//
//
//
TLangId
TLocaleString::GetSystemLangId()
{
return ::GetSystemDefaultLangID();
}
//
//
//
TLangId
TLocaleString::GetUserLangId()
{
return ::GetUserDefaultLangID();
}
//
//
//
int
TLocaleString::CompareLang(const char far* s1, const char far* s2, TLangId lang)
{
return ::CompareStringA(lang, NORM_IGNORECASE | NORM_IGNORENONSPACE,
s1,-1, s2,-1) - 2;
}
#endif